home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 501-525 / disk_514 / dkbtrace / dump2iff.lzh / dump2iff.c < prev    next >
C/C++ Source or Header  |  1991-06-08  |  14KB  |  523 lines

  1. /*****************************************************************************
  2. *
  3. *                                   dump2iff.c
  4. *
  5. *   from DKBTrace (c) 1990  David Buck
  6. *
  7. *  This file converts the raw output from the ray tracer into HAM files.
  8. *
  9. * This software is freely distributable. The source and/or object code may be
  10. * copied or uploaded to communications services so long as this notice remains
  11. * at the top of each file.  If any changes are made to the program, you must
  12. * clearly indicate in the documentation and in the programs startup message
  13. * who it was who made the changes. The documentation should also describe what
  14. * those changes were. This software may not be included in whole or in
  15. * part into any commercial package without the express written consent of the
  16. * author.  It may, however, be included in other public domain or freely
  17. * distributed software so long as the proper credit for the software is given.
  18. *
  19. * This software is provided as is without any guarantees or warranty. Although
  20. * the author has attempted to find and correct any bugs in the software, he
  21. * is not responsible for any damage caused by the use of the software.  The
  22. * author is under no obligation to provide service, corrections, or upgrades
  23. * to this package.
  24. *
  25. * Despite all the legal stuff above, if you do find bugs, I would like to hear
  26. * about them.  Also, if you have any comments or questions, you may contact me
  27. * at the following address:
  28. *
  29. *     David Buck
  30. *     22C Sonnet Cres.
  31. *     Nepean Ontario
  32. *     Canada, K2H 8W7
  33. *
  34. *  I can also be reached on the following bulleton boards:
  35. *
  36. *     OMX              (613) 731-3419
  37. *     Mystic           (613) 596-4249  or  (613) 596-4772
  38. *
  39. *  Fidonet:   1:163/109.9
  40. *  Internet:  dbuck@ccs.carleton.ca
  41. *  You Can Call Me Ray: (708) 358-5611
  42. *
  43. *
  44. *****************************************************************************/
  45.  
  46.  
  47. #define PARAMS(x) x
  48.  
  49. #include <stdio.h>
  50. #include <exec/types.h>
  51. #include <intuition/intuition.h>
  52. #include <graphics/display.h>
  53. #include <libraries/dos.h>
  54. #include <proto/all.h>
  55. #include "iff.h"
  56. #include "dump2iff.h"
  57. #include "dumproto.h"
  58.  
  59. #include <dos.h>
  60.  
  61. void main (int, char**);
  62. void exit(int);
  63. void *malloc(int);
  64. void free(void *);
  65.  
  66. extern int _bufsiz;
  67.  
  68. int amiga_close_all(void);
  69. extern char *getenv PARAMS((char *str));
  70.  
  71. struct IntuitionBase *IntuitionBase;
  72. struct GfxBase *GfxBase;
  73. struct Screen *s;
  74.  
  75. #define extract_red(x) ((x & 0xF00) >> 8)
  76. #define extract_green(x) ((x & 0x0F0) >> 4)
  77. #define extract_blue(x) (x & 0x00F)
  78.  
  79. struct NewScreen MyScreen =
  80.    {
  81.    0, 0,
  82.    SCREEN_WIDTH, SCREEN_HEIGHT,
  83.    6,
  84.    0, 1,
  85.    INTERLACE | HAM,
  86.    0,
  87.    NULL,
  88.    (UBYTE *) "dump2iff",
  89.    NULL,
  90.    NULL
  91.    };
  92.  
  93. UWORD ColourTbl[16] = { 0x000, 0x111, 0x222, 0x333, 0x444, 0x555, 0x666,
  94.                         0x777, 0x888, 0x999, 0xaaa, 0xbbb, 0xccc, 0xddd,
  95.                         0xeee, 0xfff };
  96.  
  97. LONG last_y = -1;
  98. IMAGE Raw_Image;
  99.  
  100. FILE *fp, *palette_file, *output_palette_file;
  101. char input_filename[100], palette_filename[100], output_filename[100];
  102. char output_palette_filename[100];
  103.  
  104.  
  105. int output_file, read_palette, write_palette, dithering;
  106. void get_parameters(int argc, char **argv);
  107.  
  108. void main (argc, argv) 
  109.    int argc;
  110.    char **argv;
  111.    {
  112.    unsigned int red, green, blue, i;
  113.    unsigned int x, y, index;
  114.  
  115.    if (argc < 2)
  116.      {
  117.      printf ("\nUsage:  dump2iff [options] <dump_filename> <iff_file_name> [<palette_filename>]\n");
  118.      printf ("            Options:\n");
  119.      printf ("               -d           - No dithering\n");
  120.      printf ("               -pfilename   - Write a palette file\n");
  121.      exit(0);
  122.      }
  123.  
  124.    Close_Threshold = 5;
  125.  
  126.    fp = NULL;
  127.    read_palette = FALSE;
  128.    write_palette = FALSE;
  129.    output_file = FALSE;
  130.    dithering = TRUE;
  131.  
  132.    IntuitionBase = (struct IntuitionBase *)
  133.                     OpenLibrary ("intuition.library",INT_REV);
  134.    if (IntuitionBase == NULL)
  135.       exit(FALSE);
  136.  
  137.    GfxBase = (struct GfxBase *)
  138.                       OpenLibrary ("graphics.library", GR_REV);
  139.    if (GfxBase == NULL)
  140.       exit(FALSE);
  141.  
  142.    get_parameters(argc, argv);
  143.  
  144.    printf ("Reading raw file\n");
  145.    read_raw_image (&Raw_Image, input_filename);
  146.  
  147.  
  148.    if (dithering) {
  149.       printf ("Dithering...\n");
  150.       dither(&Raw_Image);
  151.       }
  152.  
  153.    printf ("Processing...\n");
  154.    if (read_palette) {
  155.       if ((palette_file = fopen (palette_filename, "r")) == NULL) {
  156.          display_close();
  157.          exit(FALSE);
  158.          }
  159.  
  160.       for (i = 0 ; i < 16 ; i++) {
  161.          if (fscanf (palette_file, "%d %d %d", &red, &green, &blue) != 3) {
  162.             printf ("Error reading palette file\n");
  163.             exit (1);
  164.             }
  165.  
  166.          ColourTbl[i] = ((red & 0x0f) << 8) |
  167.                         ((green & 0x0f) << 4) | (blue & 0x0f);
  168.          }
  169.       }
  170.    else {
  171.       start_recording_colours();
  172.  
  173.       for (y = 0 ; y < Raw_Image.height ; y++) {
  174.          for (x = 0 ; x < Raw_Image.width ; x++) {
  175.             index = y*Raw_Image.width + x;
  176.             process (x, y, Raw_Image.red[index],
  177.                            Raw_Image.green[index],
  178.                            Raw_Image.blue[index]);
  179.          
  180.             }
  181.          }
  182.       choose_palette();
  183.       }
  184.  
  185.    /* Write out the palette file */
  186.    if (write_palette) {
  187.       if ((output_palette_file = fopen (output_palette_filename, "w")) == NULL)
  188.          {
  189.          printf ("Cannot create palette file\n");
  190.          exit (1);
  191.          }
  192.  
  193.       
  194.       for (i = 0 ; i < 16 ; i++)
  195.          fprintf (output_palette_file, "%d %d %d\n",
  196.                   extract_red(ColourTbl[i]),
  197.                   extract_green(ColourTbl[i]),
  198.                   extract_blue(ColourTbl[i]));
  199.  
  200.  
  201.       fclose(output_palette_file);
  202.       }
  203.  
  204.    printf ("Displaying...\n");
  205.  
  206.    MyScreen.Width = Raw_Image.width;
  207.    MyScreen.Height = Raw_Image.height;
  208.    if ((s = (struct Screen *) OpenScreen (&MyScreen))
  209.           == NULL)
  210.       exit (FALSE);
  211.  
  212.    ShowTitle (s, FALSE);
  213.  
  214.  
  215.    SetAPen (&(s->RastPort), 7L);
  216.    RectFill (&(s -> RastPort), 0L, 0L, SCREEN_WIDTH-1, SCREEN_HEIGHT-1);
  217.  
  218.    LoadRGB4 (&(s->ViewPort), ColourTbl, 16L);
  219.  
  220.    for (y = 0 ; y < Raw_Image.height ; y++) {
  221.       for (x = 0 ; x < Raw_Image.width ; x++) {
  222.             index = y*Raw_Image.width + x;
  223.             display_plot (x, y, Raw_Image.red[index],
  224.                                 Raw_Image.green[index],
  225.                                 Raw_Image.blue[index]);
  226.          }
  227.       }
  228.  
  229.    if (output_file)
  230.       ConvertToIFF(output_filename);
  231.  
  232.    printf ("Finished\n");
  233.    display_close();
  234.    }
  235.  
  236. void get_parameters (argc, argv)
  237.    int argc;
  238.    char **argv;
  239.    {
  240.    int i, filename_number;
  241.  
  242.    filename_number = 0;
  243.    for (i = 1 ; i < argc ; i++) {
  244.       if (argv[i][0] == '-')
  245.          switch (argv[i][1]) {
  246.             case 'd':  dithering = FALSE;
  247.                        break;
  248.  
  249.             case 'p':  strcpy (output_palette_filename, &argv[i][2]);
  250.                        write_palette = TRUE;
  251.                        break;
  252.  
  253.             default:   printf ("Unknown option\n");
  254.                        break;
  255.             }
  256.       else
  257.          switch (filename_number) {
  258.             case 0: strcpy (input_filename, argv[i]);
  259.                     filename_number++;
  260.                     break;
  261.  
  262.             case 1: strcpy (output_filename, argv[i]);
  263.                     output_file = TRUE;
  264.                     filename_number++;
  265.                     break;
  266.  
  267.             case 2: strcpy (palette_filename, argv[i]);
  268.                     filename_number++;
  269.                     read_palette = TRUE;
  270.                     break;
  271.  
  272.             default: printf ("Too many filenames in commandline\n");
  273.                      exit(1);
  274.             }
  275.       }
  276.    if (filename_number == 0) {
  277.       printf ("No input file specified\n");
  278.       exit(1);
  279.       }
  280.    }
  281.  
  282.  
  283. void display_close ()
  284.    {
  285.    if (fp != NULL)
  286.       fclose (fp);
  287.    CloseScreen (s);
  288.    CloseLibrary (GfxBase) ;
  289.    CloseLibrary (IntuitionBase) ;
  290.    }
  291.  
  292. void display_plot (x, y, new_red, new_green, new_blue)
  293.    LONG x, y, new_red, new_green, new_blue;
  294.    {
  295.    LONG colour, newline;
  296.  
  297.    new_red &= 0xFF;
  298.    new_green &= 0xFF;
  299.    new_blue &= 0xFF;
  300.  
  301.    new_red /= 16;
  302.    new_green /= 16;
  303.    new_blue /= 16;
  304.  
  305.    newline = 0;
  306.    if (last_y != y) {
  307.       newline = 1;
  308.       last_y = y;
  309.       reset_colours();
  310.       SetAPen (&(s -> RastPort), 0);
  311.       WritePixel (&(s -> RastPort), 0, y);
  312.       }
  313.  
  314.    colour = best_colour (new_red, new_blue, new_green);
  315.    SetAPen (&(s -> RastPort), colour);
  316.    WritePixel (&(s -> RastPort), x, y);
  317.    }
  318.  
  319.  
  320. void dither (Image)
  321.    IMAGE *Image;
  322.    {
  323.    long index;
  324.    short i, j, new_red, new_green, new_blue,
  325.        red_error, green_error, blue_error;
  326.  
  327.    red_error = 0;
  328.    green_error = 0;
  329.    blue_error = 0;
  330.  
  331.    for (j = 0 ; j < Image->height ; j++)
  332.       for (i = 0 ; i < Image->width ; i++) {
  333.          index = j * Image->width + i;
  334.          red_error = Image->red[index] % 16;
  335.          green_error = Image->green[index] % 16;
  336.          blue_error = Image->blue[index] % 16;
  337.  
  338.          if (i < Image->width-1) {
  339.             new_red = Image->red[index+1] + red_error * 7 / 16;
  340.             new_green = Image->green[index+1] + green_error * 7 / 16;
  341.             new_blue = Image->blue[index+1] + blue_error * 7 / 16;
  342.             Image->red[index+1] = (new_red>255) ? 255 : new_red;
  343.             Image->green[index+1] = (new_green>255) ? 255 : new_green;
  344.             Image->blue[index+1] = (new_blue>255) ? 255 : new_blue;
  345.             }
  346.  
  347.          if (j < Image->height-1) {
  348.             index += Image->width;
  349.             if (i != 0) {
  350.                new_red = Image->red[index-1] + red_error * 3 / 16;
  351.                new_green = Image->green[index-1] + green_error * 3 / 16;
  352.                new_blue = Image->blue[index-1] + blue_error * 3 / 16;
  353.                Image->red[index-1] = (new_red>255) ? 255 : new_red;
  354.                Image->green[index-1] = (new_green>255) ? 255 : new_green;
  355.                Image->blue[index-1] = (new_blue>255) ? 255 : new_blue;
  356.                }
  357.  
  358.  
  359.             new_red = Image->red[index] + red_error * 5 / 16;
  360.             new_green = Image->green[index] + green_error * 5 / 16;
  361.             new_blue = Image->blue[index] + blue_error * 5 / 16;
  362.             Image->red[index] = (new_red>255) ? 255 : new_red;
  363.             Image->green[index] = (new_green>255) ? 255 : new_green;
  364.             Image->blue[index] = (new_blue>255) ? 255 : new_blue;
  365.  
  366.             if (i < Image->width-1) {
  367.                new_red = Image->red[index+1] + red_error / 16;
  368.                new_green = Image->green[index+1] + green_error / 16;
  369.                new_blue = Image->blue[index+1] + blue_error / 16;
  370.                Image->red[index+1] = (new_red>255) ? 255 : new_red;
  371.                Image->green[index+1] = (new_green>255) ? 255 : new_green;
  372.                Image->blue[index+1] = (new_blue>255) ? 255 : new_blue;
  373.                }
  374.             }
  375.          }
  376.    }
  377.  
  378.  
  379. void process (x, y, new_red, new_green, new_blue)
  380.    LONG x, y, new_red, new_green, new_blue;
  381.    {
  382.    LONG newline;
  383.  
  384.    new_red &= 0xFF;
  385.    new_green &= 0xFF;
  386.    new_blue &= 0xFF;
  387.  
  388.    new_red /= 16;
  389.    new_green /= 16;
  390.    new_blue /= 16;
  391.  
  392.    newline = 0;
  393.    if (last_y != y) {
  394.      newline = 1;
  395.      last_y = y;
  396.      reset_colours();
  397.      }
  398.  
  399.    record_colours (new_red, new_green, new_blue);
  400.    }
  401.  
  402.  
  403. void ConvertToIFF(file_name)
  404.    char *file_name;
  405.    {
  406.    char *buffer;
  407.    BPTR file;
  408.    BOOL PutPict();
  409.  
  410.    if ((file = Open (file_name, MODE_NEWFILE)) == 0) {
  411.       printf ("\nCannot open IFF file\n");
  412.       exit (0);
  413.       }
  414.  
  415.    buffer = malloc(BUFFER_SIZE);
  416.    if (PutPict (file, &(s->ViewPort), buffer, BUFFER_SIZE))
  417.       printf ("\nIFF write error\n");
  418.    Close (file);
  419.    }
  420.  
  421. int read_raw_byte(f)
  422.    FILE *f;
  423.    {
  424.    int c;
  425.    if ((c = getc(f)) == EOF)
  426.       return (-1);
  427.    return (c);
  428.    }
  429.  
  430. int read_raw_word(f)
  431.    FILE *f;
  432.    {
  433.    int byte1, byte2;
  434.  
  435.    byte1 = read_raw_byte(f);
  436.    if (byte1 == -1)
  437.       return(-1);
  438.  
  439.    byte2 = read_raw_byte(f);
  440.    if (byte2 == -1)
  441.       return(-1);
  442.  
  443.    return (byte1 + byte2*256);
  444.    }
  445.  
  446. void read_raw_image(Image, filename)
  447.    IMAGE *Image;
  448.    char *filename;
  449.    {
  450.    FILE *f;
  451.    int byte, i, index, row, pixels;
  452.  
  453.    if ((f = fopen(filename, "rb")) == NULL) {
  454.       printf ("Cannot open raw file %s\n", filename);
  455.       exit(1);
  456.       }
  457.  
  458.    Image->width = read_raw_word(f);
  459.    if (Image->width == -1) {
  460.       printf ("Cannot read size in dump file\n");
  461.       exit(1);
  462.       }
  463.  
  464.    Image->height = read_raw_word(f);
  465.    if (Image->height == -1) {
  466.       printf ("Cannot read size in dump file: %s\n", filename);
  467.       exit(1);
  468.       }
  469.  
  470.    pixels = Image->width * Image->height;
  471.  
  472.    if (((Image->red = (unsigned char *) malloc(pixels))==NULL) ||
  473.        ((Image->green = (unsigned char *) malloc(pixels))==NULL) ||
  474.        ((Image->blue = (unsigned char *) malloc(pixels))==NULL)) {
  475.       printf ("Cannot allocate memory for picture: %s\n", filename);
  476.       exit(1);
  477.       }
  478.  
  479.    for (i = 0 ; i < pixels ; i++) {
  480.       Image->red[i] = 0;
  481.       Image->green[i] = 0;
  482.       Image->blue[i] = 0;
  483.       }
  484.  
  485.    row = read_raw_word(f);
  486.    while (row != -1) {
  487.       for (i = 0 ; i < Image->width ; i++) {
  488.          index = row*Image->width + i;
  489.  
  490.          byte = read_raw_byte(f);
  491.          if (byte == -1) {
  492.             printf ("Unexpected end of file in raw image: %s\n", filename);
  493.             exit(1);
  494.             }
  495.          Image->red[index] = byte;
  496.          }
  497.  
  498.       for (i = 0 ; i < Image->width ; i++) {
  499.          index = row*Image->width + i;
  500.  
  501.          byte = read_raw_byte(f);
  502.          if (byte == -1) {
  503.             printf ("Unexpected end of file in raw image: %s\n", filename);
  504.             exit(1);
  505.             }
  506.          Image->green[index] = byte;
  507.          }
  508.  
  509.       for (i = 0 ; i < Image->width ; i++) {
  510.          index = row*Image->width + i;
  511.  
  512.          byte = read_raw_byte(f);
  513.          if (byte == -1) {
  514.             printf ("Unexpected end of file in raw image: %s\n", filename);
  515.             exit(1);
  516.             }
  517.          Image->blue[index] = byte;
  518.          }
  519.       row = read_raw_word(f);
  520.       }
  521.    fclose (f);
  522.    }
  523.